package com.cskaoyan.javase.object._4finalize;

/**
 * @description: finalize方法
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

import java.util.Scanner;

/**
 * finalize方法的声明:
 *       protected void finalize() throws Throwable { }
 * 首先注意访问权限是protected,其次它的方法体是空的
 * - Object()类当中的finalize()方法是protected权限，并且是空的
 * - 完全可以看得出来，该方法需要子类自己重写去实现功能
 * - 这种方法比接口的抽象方法要自由，因为它不是强制的
 *  throws Throwable 这是方法中抛出异常列表的声明,现在不管它
 *
 *  finalize方法的作用:
 *
 *      C++中跟对象生命周期相关的两种方法:
 *          1.构造函数/构造器: 和Java中的类似,负责对象的"出生",给成员变量赋值
 *          2.析构函数: 对象被销毁时,负责对象的"善后"工作
 *      C++当中对象的内存回收和Java的GC是类似的,无非是一个自动,一个手动,但是对象所占用的内存空间都是可以被正常回收的
 *      而有些时候,对象不仅自身占用内存空间,还需要使用一些额外的资源
 *      比如做I/O操作时,需要占用系统的I/O资源,再比如网络编程,占用网络资源等等
 *      这些额外的资源,对象内存被释放后,仍然可能存在占用情况,需要程序员额外的操作去回收它们
 *      C++当中的析构函数就是完成这个功能的,在对象销毁时,自动被调用,自动去释放对象占用的系统资源
 *
 *      Java当中的finalize方法就是模仿析构函数产生的,finalize方法也会在对象销毁时自动被调用,我们java程序员只需要把释放资源的代码放在finalize方法中,可以近似完成析构函数的作用
 *
 *      理想是这样的,但实际上完成不了,
 *          这里就体现Java GC垃圾回收的缺点: 程序员缺乏对垃圾回收的控制,垃圾回收具有不确定性,没有时效性
 * 连带着finalize方法的执行也是不确定的,而释放资源的占用和释放是很重要的事情,不能把重要的事情依赖于一个不稳定的机制
 * 所以Java当中对 对象占用系统资源的释放是全手动的,这是GC全自动垃圾回收的代价
 *
 */
public class Demo {
    public static void main(String[] args) {
        new Student(); //匿名对象
        System.gc(); //该方法用于通知GC进行垃圾回收,但是这个方法没有意义,通知不是强制的

    }
}

class Student {
    @Override
    protected void finalize() throws Throwable {
        System.out.println("模拟释放系统资源~~~");
    }
}
